import React, {useState, useEffect} from 'react';
import {Tree, Popconfirm, Table, Modal, Typography, message, Tooltip } from 'antd';
import { Scrollbars } from 'react-custom-scrollbars';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import memo from '../common/wrapMemo';
import Header from '../header/Header';
import MapModel from './MapModel';
import api from '../../api';
import Loading from '../common/Loading';
import modules from '../../store/modules';
import {formatTime} from '../../util/util';
import FeatureEdit from './FeatureEdit';
import FeatureAdd from './FeatureAdd';

import style from './DataManage.module.scss';

const { actionCreators } = modules;

let curLayerName = '';
let curLayerCode = '';

const DataManage = memo((props) => {
    const {layerFields, userInfo, dispatch} = props;
    const fields = layerFields.toJS();
    const { roleId } = userInfo.toJS().role;

    const [data, setData] = useState([]);
    const [treeData, setTreeData] = useState([]);                                   // 图层树数据
    const [defaultExpandedKeys, setDefaultExpandedKeys] = useState(['0-0-0']);      // 图层树默认展开key
    const [defaultSelectedKeys, setDefaultSelectedKeys] = useState([]);             // 图层树默认选中key
    const [pagination, setPagination] = useState({current: 1, pageSize: 10});       // 表格分页信息
    const [isMapModalVisible, setIsMapModelVisible] = useState(false);              // 地图model显隐
    const [columns, setColumns] = useState([]);                                     // 图层要素表格表头
    const [editShow, setEditShow] = useState(false);   
    const [editData, setEditData] = useState({});
    const [featureDetail, setFeatureDetail] = useState('point');
    const [addShow, setAddShow] = useState(false);
    const [allFields, setAllFields] = useState([]);
    // const [units, setUnits] = useState({});
    const [featureType, setFeatureType] = useState('1');                            // 要素类型  1：点   3：面
    const [selectedKeys, setSelectedKeys] = useState([]);

    const [treeLoading, setTreeLoading] = useState(false);                          // 图层树加载状态
    const [tableLoading, setTableLoading] = useState(false);                        // 表格数据加载状态
    const [addLoading, setAddLoading] = useState(false);                            // 添加要素loading
    const [saveLoading, setSaveLoading] = useState(false);                          // 编辑要素loading

    useEffect(() => {
        const length = Object.keys(layerFields.toJS()).length;
        if(length === 0){
            getLayerFields();
        }else{
            // 获取图层树
            getTreeData();
        }
    },[layerFields]);

    // 获取图层名称字典表
    const getLayerFields = () => {
        api.search.queryLayerFields().then((res) => {
            const {code, data} = res.data;
            if(code === 200){
                dispatch(actionCreators.layer.update(data));
                // getTreeData();
            }
        }).catch(err => {
            console.log(err);
        })
    };

    // 获取图层树数据
    const getTreeData = () => {
        setTreeLoading(true);
        api.search.queryLayerTree()
            .then((res) => {
                const {code, data} = res.data;
                if(code === 200){
                    const treeData = generateTreeData(data);
                    const {defaultExpandKey, defaultSelectedKey, defaultCode} = getDefaultKey(treeData);
                    setDefaultExpandedKeys([defaultExpandKey]);
                    setSelectedKeys([defaultSelectedKey]);
                    setDefaultSelectedKeys([defaultSelectedKey]);
                    curLayerCode = defaultCode;
                    setTreeData(treeData);
                    // 获取图层属性表
                    const params = {
                        code: defaultCode,
                        page: 1,
                        size: 10
                    };
                    getLayerFeatureTable(params);
                }
            }).catch((err) => {
                console.log(err);
            }).finally(() => {
                setTreeLoading(false);
            });
    };

    // 获取图层要素表格数据
    const getLayerFeatureTable = (params) => {
        const {page, size, code} = params;

        const qureyParams = {
            code, 
            pageParam: {
                page,
                size
            }
        }
        setTableLoading(true);
        api.search.queryLayerList(qureyParams)
            .then((res) => {
                const {code, data} = res.data;
                if(code === 200) {
                    const {count, result=[]} = data;
                    setPagination({
                        current: page,
                        pageSize: size,
                        total: count, 
                    });

                    if(result.length > 0){
                        const dataSource = result.map((item, index) => {
                            return {
                                ...item,
                                key: item.uid ? item.uid : index
                            };
                        });
                        setData(dataSource);
                    }else{
                        setData([]);
                    }
                }
            }).catch(err => {
                console.log(err);
            }).finally(() => {
                setTableLoading(false);
            });
    };

    // 删除数据
    const deleteFeature = (record) => {
        const {uid} = record;
        const code = curLayerCode;
        const params = {
            uid, 
            code
        };

        api.search.deleteFeature(params)
            .then(res => {
                const {code} = res.data;
                if(code === 200) {
                    message.success('要素删除成功!');
                    // 获取图层属性表
                    const params = {
                        page: pagination.current,
                        size: pagination.pageSize,
                        code: curLayerCode
                    };
                    getLayerFeatureTable(params);
                }else{
                    message.err('要素删除失败!');
                }
            }).catch(err => {
                console.log(err);
                message.error('要素删除失败!');
            })
    };

    const getTitle = (title) => {
        return <Tooltip placement='bottom' title={<div>{title}</div>}>
                    <span>{title}</span>
                </Tooltip>
    };

    // 获取表格表头数据
    const getColumns = (allFields, units) => {
        let columns = [];
        const operation = {
            title: '操作',
            width: 150,
            fixed: 'right',
            dataIndex: 'operation',
            render (_, record) {
                return (
                    <>
                        <Typography.Link onClick={() => edit(record)} style={{
                            marginRight: 8,
                        }}>
                            编辑
                        </Typography.Link>
                        {
                            roleId === 1 && 
                            <Typography.Link style={{ marginRight: 8}}>
                                <Popconfirm
                                    title="您确定删除此数据吗？"
                                    onConfirm={() => deleteFeature(record)}
                                    okText="确定"
                                    cancelText="取消"
                                >
                                    <span>删除</span>
                                </Popconfirm>
                            </Typography.Link>
                        }
                        <Typography.Link onClick={() => draw(record)}>
                            绘图
                        </Typography.Link>
                    </>
                );
            }
        };
        
        allFields.forEach((key, index) => {
            key = key.replaceAll('_','');
            if(key !== 'uid' && key !== 'image'){
                const name = fields[key] ? fields[key] : key;
                const title = units[key] ? `${name}(${units[key]})` : name;
                let column = {};

                if(key === 'updateTime'){
                    column = {
                        title: '更新时间',
                        dataIndex: key,
                        width: 120,
                        key: index,
                        render(_, record) {
                            return <span>{formatTime(record.updateTime)}</span>;
                        }
                    };
                }else if(title.includes('时间')){
                    column = {
                        title: title,
                        dataIndex: key,
                        width: 120,
                        key: index,
                        render(_, record) {
                            return <span>{formatTime(record.updateTime)}</span>;
                        }
                    };
                    
                }else{
                    column = {
                        title: getTitle(title),
                        dataIndex: key,
                        width: 100,
                        key: index
                    };
                }
                columns.push(column);
            }
            
        });
        columns.push(operation);

        return columns;
    };

    // 构造图层树数据
    const generateTreeData = (datas) => {
        let treeDatas = [];

        const recursive = (treeChildren, key, datas) => {
            datas.forEach((data) => {
                let childrenData = {}; 
                const {name, code, isClassify, fields} = data;
                childrenData['title'] = name;
                childrenData['key'] = `${key}-${code}`;
                childrenData['code'] = code;
                childrenData['isClassify'] = isClassify;
                childrenData['fields'] = fields;
                if(data['children']){
                    childrenData['children'] = [];
                    recursive(childrenData.children, childrenData['key'], data['children']);
                }
                treeChildren.push(childrenData);
            });
        };

        recursive(treeDatas, 0, datas);

        return treeDatas;
    };

    // 获取第一个图层父级key
    const getDefaultKey = (treeData) => {
        let defaultExpandKey = '', defaultSelectedKey = '', defaultCode = '';
        const recursive = (treeData) => {
            const {children, key, code, title, fields, featureType='1'} = treeData;
            if(children.length > 0){
                recursive(children[0]);
            }else{
                const arr = key.split('-');
                const newArr = arr.splice(0, arr.length - 1);
                defaultSelectedKey = key;
                defaultExpandKey = newArr.join('-');
                defaultCode = code;
                curLayerName = title;
                const {all, units={}} = fields;
                
                const allArr = all.split(',');
                const columns = getColumns(allArr, units);
                setColumns(columns);
                setAllFields(allArr);
                // setUnits(units);
                setFeatureType(featureType);
            }
        };

        recursive(treeData[0]);

        return {
            defaultExpandKey, 
            defaultSelectedKey,
            defaultCode
        };
    };

    // 页码变化事件
    const pageChange = (page, pageSize) => {
        const params = {
            code: curLayerCode,
            page: page,
            size: pageSize
        };
        getLayerFeatureTable(params);
    };

    // 图层树节点选中事件
    const onSelect = (selectedKeys, e) =>{
        const {children, code, title, fields={}, featureType = '3', key} = e.node; 
        
        setSelectedKeys([key]);
        if(children.length === 0){
            const {all='', units={}} = fields;
            setPagination({current:1, pageSize: 10});
            const params = {
                page: 1,
                size: 10,
                code
            };
            getLayerFeatureTable(params);
            curLayerCode = code;
            curLayerName = title;
            setFeatureType(featureType);
            const allArr = all.split(',');
            const columns = getColumns(allArr, units);
            setColumns(columns);
            setAllFields(allArr);
            // setUnits(units);
        }
    };

    const edit = (record) => {
        setEditData(record);
        setEditShow(true);
    };

    // 编辑要素属性及geojson
    const updateFeature = (val) => {
        const params = {
            ...val,
            operationLayer: curLayerCode? curLayerCode : ''
        };
        
        console.log(curLayerName);
       
        api.search.saveFeature(params)
            .then((res) => {
                const {code} = res.data;
                if(code === 200){
                    message.success('要素保存成功!');
                    const params = {
                        page: pagination.current,
                        size: pagination.pageSize,
                        code: curLayerCode
                    };
                    getLayerFeatureTable(params);
                }else{
                    message.error('要素保存失败!');
                }
            }).catch(err => {
                console.log(err);
                message.error('要素保存失败!');
                setSaveLoading(false);
            });
    };

    // 导出图层
    const exportLayer  = () => {
        if(!curLayerCode) return;
        const url = `${origin}/webapi/2.0/export/excel?code=${curLayerCode}`;
        window.open(url, "_blank");
    };

    // 绘制
    const draw = (record) => {
        getFeatureDetail(record);
    };

    // 获取要素详情
    const getFeatureDetail = (record) => {
        const {uid} = record;
        const param = {
            uid,
            code: curLayerCode
        }
        api.search.queryFeatureInfo(param)
            .then(res => {
                const {code, data} = res.data;
                if(code === 200){
                    setFeatureDetail(data);
                    setIsMapModelVisible(true);
                }else{
                    message.error('要素详情获取失败!');
                }
            }).catch(err => {
                console.log(err);
            })
    };

    // 添加要素
    const addFeature = ({temp, values}) => {
        const params = {
            code: curLayerCode,
            feature: {
                ...values
            },
            temp
        };
        setAddLoading(true);
        api.search.addFeature(params)
            .then((res) => {
                const {code} = res.data;
                if(code === 200){
                    message.success('要素保存成功!');
                    setAddShow(false);
                    const params = {
                        page: pagination.current,
                        size: pagination.pageSize,
                        code: curLayerCode
                    };
                    getLayerFeatureTable(params);
                }else{
                    message.error('要素保存失败!');
                }
            }).catch((err) => {
                console.log(err);
                message.error('要素保存失败!');
            }).finally(() => {
                setAddLoading(false);
            });
    };

    return (
        <>
            <Header />
            <div className={style.dataManage}>
                <div className={style.left}>
                    <div className={style.header}>
                        <span>目录</span>
                        {
                            roleId === 1 &&
                            <div className={style.btns} >
                                <span onClick={exportLayer}>导出</span>
                            </div>
                        }
                    </div>
                    <div className={style.layerTree}>
                        {
                        treeLoading ? 
                            <Loading />:
                            <Scrollbars autoHeight autoHeightMin={0} autoHeightMax={`calc(100vh - 170px)`}>
                                <Tree
                                    defaultExpandedKeys={defaultExpandedKeys}
                                    defaultSelectedKeys={defaultSelectedKeys}
                                    selectedKeys={selectedKeys}
                                    onSelect={onSelect}
                                    treeData={treeData}/>
                            </Scrollbars>
                        }
                    </div>
                </div>
                <div className={style.right}>
                    <div className={style.header} onClick={() => setAddShow(true)}>
                        新增一行
                    </div>
                    <div className={style.tableBox}>
                        <Table
                            loading={tableLoading}
                            bordered
                            dataSource={data}
                            columns={columns}
                            scroll={{x: 500, y: window.innerHeight - 240}}
                            pagination={{...pagination, onChange:pageChange}}
                        />
                    </div>
                </div>
            </div>
            { 
                isMapModalVisible && 
                    <MapModel 
                        operationType='edit'
                        featureDetail={featureDetail}
                        updateFeature={updateFeature}
                        featureType={featureType}
                        isMapModalVisible={isMapModalVisible}
                        setIsMapModelVisible={setIsMapModelVisible}/>
            }
            {
                editShow && 
                <Modal title="要素编辑" visible={editShow} onOk={() => setEditShow(false)} onCancel={() => setEditShow(false)} footer={null}>
                    <FeatureEdit 
                        editData={editData}
                        fieldNames={fields}
                        saveLoading={saveLoading}
                        updateFeature={updateFeature}
                        setEditShow={setEditShow}/>
                </Modal>
            }
            {
                <Modal title="要素新增" visible={addShow} onOk={() => setAddShow(false)} onCancel={() => setAddShow(false)} footer={null}>
                    <FeatureAdd 
                        fields={allFields}
                        fieldNames={fields}
                        addLoading = {addLoading}
                        addFeature={addFeature}
                        setAddShow={setAddShow}/>
                </Modal>
            }
        </>
    )
});

DataManage.displayName = 'DataManage';

Map.propTypes = {
    layerFields: PropTypes.object
}   

function mapStateToProps(state) {
    return {
        userInfo: state.get('userInfo'),
        layerFields: state.getIn(['layer','layerFields'])
    };
}

export default connect(mapStateToProps)(DataManage);

